package com.stars.questions.commonQuestion.publish.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.stars.base.entity.Result;
import com.stars.module.code.service.CodeService;
import com.stars.questions.commonQuestion.common.entity.CommonConstants;
import com.stars.questions.commonQuestion.config.entity.QuestionsCommonConfig;
import com.stars.questions.commonQuestion.config.entity.QuestionsCommonConfigSub;
import com.stars.questions.commonQuestion.config.service.QuestionsCommonConfigService;
import com.stars.questions.commonQuestion.publish.entity.CommonReply;
import com.stars.questions.commonQuestion.publish.entity.CommonReplyItem;
import com.stars.questions.commonQuestion.publish.mapper.CommonReplyItemMapper;
import com.stars.questions.commonQuestion.publish.mapper.CommonReplyMapper;
import com.stars.questions.commonQuestion.publish.service.CommonPublishService;
import com.stars.questions.deptQuestion.census.entity.TotalCensus;
import com.stars.util.cache.CacheUtil;
import com.stars.util.common.DevelopKit;
import com.stars.util.common.IpLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class CommonPublishServiceImpl implements CommonPublishService {

    private final CacheUtil cacheUtil;
    private final QuestionsCommonConfigService configService;
    private final CodeService codeService;
    private final CommonReplyMapper replyMapper;
    private final SqlSessionFactory sqlSessionFactory;
    private final CommonReplyItemMapper replyItemMapper;
    private final String IP_REDIS = "question-ip:";

    public CommonPublishServiceImpl(CacheUtil cacheUtil, QuestionsCommonConfigService configService, CodeService codeService, CommonReplyMapper replyMapper, SqlSessionFactory sqlSessionFactory,CommonReplyItemMapper replyItemMapper) {
        this.cacheUtil = cacheUtil;
        this.configService = configService;
        this.codeService = codeService;
        this.replyMapper = replyMapper;
        this.sqlSessionFactory = sqlSessionFactory;
        this.replyItemMapper = replyItemMapper;
    }

    @Override
    public JSONObject loadQuestion(String id) {

        JSONObject result = new JSONObject();
        result.put("result",false);

        if (!StringUtils.hasLength(id)) {
            result.put("msg","未指定问卷！");
            return result;
        }

        QuestionsCommonConfig question = configService.getPublishQuestion(id);

        if (question == null) {
            result.put("msg","调查问卷尚未开始！");
            return result;
        }

        if (!StringUtils.hasLength(question.getId())) {
            result.put("msg","调查问卷获取失败！");
            return result;
        }

        List<QuestionsCommonConfigSub> list = cacheUtil.getValueByList(CommonConstants.PUBLISH_QUESTION_PREFIX + question.getId() , QuestionsCommonConfigSub.class);

        if (list == null || list.isEmpty()) {
            list = configService.loadQuestionSub(question.getId());
            if (list == null || list.isEmpty()) {
                result.put("msg", "调查问卷未维护！");
                return result;
            }
            for (QuestionsCommonConfigSub configSub : list) {
                if (StringUtils.hasLength(configSub.getCode())) {
                    configSub.setCodeSelect(codeService.getCode(configSub.getCode()));
                }
            }
            cacheUtil.setValue(CommonConstants.PUBLISH_QUESTION_PREFIX + question.getId(), list);
        }
        Set<Integer> set = configService.generateRandomNum(question,list.size());

        List<QuestionsCommonConfigSub> relist;
        if(set==null){
            relist = list;
        }else{
            relist = new ArrayList<>();
            for(Integer index : set){
                relist.add(list.get(index));
            }
        }

        result.put("result",true);
        result.put("array",relist);
        result.put("questionConfig",question);

        return result;
    }

    @Override
    public Result saveReply(HttpServletRequest request, CommonReply reply) {
        // 问卷配置ID
        String configId = reply.getConfigId();
        String ip = IpLocalUtil.getIPAddress(request);
        reply.setIp(ip);
        reply.setIpLocation(IpLocalUtil.getIPLocation(ip));

        Object obj = cacheUtil.getValue(false, IP_REDIS + ip);

        if (obj != null) {
            return Result.error("感谢您已参与过本次问卷调查!");
        }

        cacheUtil.setValue(false, IP_REDIS + ip, "1", 60*60);

        if(!StringUtils.hasLength(configId)){
            return Result.error("提交失败，未找到要提交的问卷信息。");
        }

        QuestionsCommonConfig question = configService.loadQuestionData(configId);

        if(question.getPublish()!=1 || question.getStartDate()==null || question.getEndDate()==null
                || new Date().getTime()<question.getStartDate().getTime()
                || new Date().getTime()>question.getEndDate().getTime()){
            return Result.error("提交失败，问卷调查尚未开始。");
        }

        boolean result = true;
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
        CommonReplyMapper mainMapper = sqlSession.getMapper(CommonReplyMapper.class);
        CommonReplyItemMapper itemMapper = sqlSession.getMapper(CommonReplyItemMapper.class);

        try {
            //保存主表
            String replyId = DevelopKit.generateUUID();
            reply.setId(replyId);
            reply.setCreateDate(new Date());
            DevelopKit.setBaseInfo(reply);

            mainMapper.insert(reply);
            //保存子表
            List<CommonReplyItem> subList = reply.getQuestions();

            for (CommonReplyItem sub : subList) {
                sub.setId(DevelopKit.generateUUID());
                sub.setFid(replyId);
                DevelopKit.setBaseInfo(sub);

                itemMapper.insert(sub);
            }
            // 提交
            sqlSession.commit();

        }catch (Exception e){
            log.error(e.getMessage());
            sqlSession.rollback();
            result = false;
        }finally {
            try {
                sqlSession.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        if(!result){
            return Result.error("数据提交失败，请检查填写的信息。");
        }

        return Result.success();
    }

    @Override
    public JSONObject loadQuestionListByConfigId(CommonReplyItem item) {
        JSONArray array = new JSONArray();
        List<CommonReplyItem> list = replyItemMapper.loadQuestionListByConfigId(item);
        if(!list.isEmpty()) {
            array = JSONArray.parseArray(JSON.toJSONString(list));
        }
        JSONObject object = new JSONObject();
        object.put("list",array);
        object.put("total",list.size());
        return object;
    }

    /**
     * @Author mango
     * @Description 临时刷数据
     * @Date 2025/4/16 14:59
     */
    @Override
    public void flushData() {
        LambdaQueryWrapper<CommonReply> replyWrapper = new LambdaQueryWrapper<>();
        replyWrapper.isNull(CommonReply::getIpLocation);
        List<CommonReply> list = replyMapper.selectList(replyWrapper);
        if(!list.isEmpty()){
//            int numberOfThreads = 10;
//            ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);

            for (CommonReply item : list) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
//                executorService.submit(() -> {
                    if(StringUtils.hasLength(item.getIp())) {
                        item.setIpLocation(IpLocalUtil.getIPLocation(item.getIp()));
                        replyMapper.updateById(item);
                    }
//                });
            }

//            executorService.shutdown();
//            try {
//                executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
//            } catch (InterruptedException e) {
//                log.error("线程池等待终止时发生中断", e);
//            }
        }
    }


    private boolean checkSubmit (CommonReply reply) {
        LambdaQueryWrapper<CommonReply> replyWrapper = new LambdaQueryWrapper<>();
        replyWrapper.eq(CommonReply::getConfigId, reply.getConfigId())
                .eq(CommonReply::getMobile, reply.getMobile());

        return replyMapper.exists(replyWrapper);
    }
}
